Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

.specify/extensions/git/scripts/bash/auto-commit.sh fix/qr-error-correction (7b45f84f) Text, 4.87 KB

T8b949e#!/usr/bin/env bash
T8b949e# Git extension: auto-commit.sh
T8b949e# Automatically commit changes after a Spec Kit command completes.
T8b949e# Checks per-command config keys in git-config.yml before committing.
T8b949e#
T8b949e# Usage: auto-commit.sh <event_name>
T8b949e# e.g.: auto-commit.sh after_specify

Tffa657set -e

Te6edf3EVENT_NAMETff7b72=Ta5d6ff"Tffd700${Te6edf31Tff7b72:-Tffd700}Ta5d6ff"
Tff7b72if Tff7b72[ -z Ta5d6ff"Te6edf3$EVENT_NAMETa5d6ff" Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Ta5d6ffUsage: Te6edf3$0Ta5d6ff <event_name>Ta5d6ff" >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff1
Tff7b72fi

Te6edf3SCRIPT_DIRTff7b72=Ta5d6ff"Tff7b72$(Te6edf3CDPATHTff7b72=Ta5d6ff"" Tffa657cd Ta5d6ff"Tff7b72$(dirname Ta5d6ff"Tffd700${Te6edf3BASH_SOURCETb4b4b4[0]Tffd700}Ta5d6ff"Tff7b72)Ta5d6ff" Tff7b72&& Tffa657pwdTff7b72)Ta5d6ff"

_find_project_rootTff7b72(Tff7b72) Tff7b72{
Tffa657local Te6edf3dirTff7b72=Ta5d6ff"Te6edf3$1Ta5d6ff"
Tff7b72while Tff7b72[ Ta5d6ff"Te6edf3$dirTa5d6ff" !Tff7b72= Ta5d6ff"/" Tff7b72]Tb4b4b4; Tff7b72do
Tff7b72if Tff7b72[ -d Ta5d6ff"Te6edf3$dirTa5d6ff/.specifyTa5d6ff" Tff7b72] Tff7b72|| Tff7b72[ -d Ta5d6ff"Te6edf3$dirTa5d6ff/.gitTa5d6ff" Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Te6edf3$dirTa5d6ff"
Tff7b72return T79c0ff0
Tff7b72fi
Te6edf3dirTff7b72=Ta5d6ff"Tff7b72$(dirname Ta5d6ff"Te6edf3$dirTa5d6ff"Tff7b72)Ta5d6ff"
Tff7b72done
Tff7b72return T79c0ff1
Tff7b72}

Te6edf3REPO_ROOTTff7b72=Tff7b72$(_find_project_root Ta5d6ff"Te6edf3$SCRIPT_DIRTa5d6ff"Tff7b72) Tff7b72|| Te6edf3REPO_ROOTTff7b72=Ta5d6ff"Tff7b72$(Tffa657pwdTff7b72)Ta5d6ff"
Tffa657cd Ta5d6ff"Te6edf3$REPO_ROOTTa5d6ff"

T8b949e# Check if git is available
Tff7b72if ! Tffa657command -v git >/dev/null T79c0ff2>Tb4b4b4&T79c0ff1Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"[specify] Warning: Git not found; skipped auto-commit" >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff0
Tff7b72fi

Tff7b72if ! git rev-parse --is-inside-work-tree >/dev/null T79c0ff2>Tb4b4b4&T79c0ff1Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"[specify] Warning: Not a Git repository; skipped auto-commit" >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff0
Tff7b72fi

T8b949e# Read per-command config from git-config.yml
Te6edf3_config_fileTff7b72=Ta5d6ff"Te6edf3$REPO_ROOTTa5d6ff/.specify/extensions/git/git-config.ymlTa5d6ff"
Te6edf3_enabledTff7b72=Tffa657false
Te6edf3_commit_msgTff7b72=Ta5d6ff""

Tff7b72if Tff7b72[ -f Ta5d6ff"Te6edf3$_config_fileTa5d6ff" Tff7b72]Tb4b4b4; Tff7b72then
T8b949e# Parse the auto_commit section for this event.
T8b949e# Look for auto_commit.<event_name>.enabled and .message
T8b949e# Also check auto_commit.default as fallback.
Te6edf3_in_auto_commitTff7b72=Tffa657false
Te6edf3_in_eventTff7b72=Tffa657false
Te6edf3_default_enabledTff7b72=Tffa657false

Tff7b72while Te6edf3IFSTff7b72= Tffa657read -r _lineTb4b4b4; Tff7b72do
T8b949e# Detect auto_commit: section
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -q Ta5d6ff'^auto_commit:'Tb4b4b4; Tff7b72then
Te6edf3_in_auto_commitTff7b72=Tffa657true
Te6edf3_in_eventTff7b72=Tffa657false
Tff7b72continue
Tff7b72fi

T8b949e# Exit auto_commit section on next top-level key
Tff7b72if Te6edf3$_in_auto_commit Tff7b72&& Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff'^[a-z]'Tb4b4b4; Tff7b72then
Tff7b72break
Tff7b72fi

Tff7b72if Te6edf3$_in_auto_commitTb4b4b4; Tff7b72then
T8b949e# Check default key
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff"^[[:space:]]+default:[[:space:]]"Tb4b4b4; Tff7b72then
Te6edf3_valTff7b72=Tff7b72$(Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| sed Ta5d6ff's/^[^:]*:[[:space:]]*//' Tb4b4b4| tr -d Ta5d6ff'[:space:]' Tb4b4b4| tr Ta5d6ff'[:upper:]' Ta5d6ff'[:lower:]'Tff7b72)
Tff7b72[ Ta5d6ff"Te6edf3$_valTa5d6ff" Tff7b72= Ta5d6ff"true" Tff7b72] Tff7b72&& Te6edf3_default_enabledTff7b72=Tffa657true
Tff7b72fi

T8b949e# Detect our event subsection
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff"Ta5d6ff^[[:space:]]+Tffd700${Te6edf3EVENT_NAMETffd700}Ta5d6ff:Ta5d6ff"Tb4b4b4; Tff7b72then
Te6edf3_in_eventTff7b72=Tffa657true
Tff7b72continue
Tff7b72fi

T8b949e# Inside our event subsection
Tff7b72if Te6edf3$_in_eventTb4b4b4; Tff7b72then
T8b949e# Exit on next sibling key (same indent level as event name)
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff'^[[:space:]]{2}[a-z]' Tff7b72&& ! Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff'^[[:space:]]{4}'Tb4b4b4; Tff7b72then
Te6edf3_in_eventTff7b72=Tffa657false
Tff7b72continue
Tff7b72fi
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff'[[:space:]]+enabled:'Tb4b4b4; Tff7b72then
Te6edf3_valTff7b72=Tff7b72$(Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| sed Ta5d6ff's/^[^:]*:[[:space:]]*//' Tb4b4b4| tr -d Ta5d6ff'[:space:]' Tb4b4b4| tr Ta5d6ff'[:upper:]' Ta5d6ff'[:lower:]'Tff7b72)
Tff7b72[ Ta5d6ff"Te6edf3$_valTa5d6ff" Tff7b72= Ta5d6ff"true" Tff7b72] Tff7b72&& Te6edf3_enabledTff7b72=Tffa657true
Tff7b72[ Ta5d6ff"Te6edf3$_valTa5d6ff" Tff7b72= Ta5d6ff"false" Tff7b72] Tff7b72&& Te6edf3_enabledTff7b72=Tffa657false
Tff7b72fi
Tff7b72if Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| grep -Eq Ta5d6ff'[[:space:]]+message:'Tb4b4b4; Tff7b72then
Te6edf3_commit_msgTff7b72=Tff7b72$(Tffa657echo Ta5d6ff"Te6edf3$_lineTa5d6ff" Tb4b4b4| sed Ta5d6ff's/^[^:]*:[[:space:]]*//' Tb4b4b4| sed Ta5d6ff's/^["'Tffea00\'Ta5d6ff']//' Tb4b4b4| sed Ta5d6ff's/["'Tffea00\'Ta5d6ff']*$//'Tff7b72)
Tff7b72fi
Tff7b72fi
Tff7b72fi
Tff7b72done < Ta5d6ff"Te6edf3$_config_fileTa5d6ff"

T8b949e# If event-specific key not found, use default
Tff7b72if Tff7b72[ Ta5d6ff"Te6edf3$_enabledTa5d6ff" Tff7b72= Ta5d6ff"false" Tff7b72] Tff7b72&& Tff7b72[ Ta5d6ff"Te6edf3$_default_enabledTa5d6ff" Tff7b72= Ta5d6ff"true" Tff7b72]Tb4b4b4; Tff7b72then
T8b949e# Only use default if the event wasn't explicitly set to false
T8b949e# Check if event section existed at all
Tff7b72if ! grep -q Ta5d6ff"Ta5d6ff^[[:space:]]*Tffd700${Te6edf3EVENT_NAMETffd700}Ta5d6ff:Ta5d6ff" Ta5d6ff"Te6edf3$_config_fileTa5d6ff" T79c0ff2>/dev/nullTb4b4b4; Tff7b72then
Te6edf3_enabledTff7b72=Tffa657true
Tff7b72fi
Tff7b72fi
Tff7b72else
T8b949e# No config file — auto-commit disabled by default
Tffa657exit T79c0ff0
Tff7b72fi

Tff7b72if Tff7b72[ Ta5d6ff"Te6edf3$_enabledTa5d6ff" !Tff7b72= Ta5d6ff"true" Tff7b72]Tb4b4b4; Tff7b72then
Tffa657exit T79c0ff0
Tff7b72fi

T8b949e# Check if there are changes to commit
Tff7b72if git diff --quiet HEAD T79c0ff2>/dev/null Tff7b72&& git diff --cached --quiet T79c0ff2>/dev/null Tff7b72&& Tff7b72[ -z Ta5d6ff"Tff7b72$(git ls-files --others --exclude-standard T79c0ff2>/dev/nullTff7b72)Ta5d6ff" Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Ta5d6ff[specify] No changes to commit after Te6edf3$EVENT_NAMETa5d6ff" >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff0
Tff7b72fi

T8b949e# Derive a human-readable command name from the event
T8b949e# e.g., after_specify -> specify, before_plan -> plan
Te6edf3_command_nameTff7b72=Tff7b72$(Tffa657echo Ta5d6ff"Te6edf3$EVENT_NAMETa5d6ff" Tb4b4b4| sed Ta5d6ff's/^after_//' Tb4b4b4| sed Ta5d6ff's/^before_//'Tff7b72)
Te6edf3_phaseTff7b72=Tff7b72$(Tffa657echo Ta5d6ff"Te6edf3$EVENT_NAMETa5d6ff" Tb4b4b4| grep -q Ta5d6ff'^before_' Tff7b72&& Tffa657echo Ta5d6ff'before' Tff7b72|| Tffa657echo Ta5d6ff'after'Tff7b72)

T8b949e# Use custom message if configured, otherwise default
Tff7b72if Tff7b72[ -z Ta5d6ff"Te6edf3$_commit_msgTa5d6ff" Tff7b72]Tb4b4b4; Tff7b72then
Te6edf3_commit_msgTff7b72=Ta5d6ff"Ta5d6ff[Spec Kit] Auto-commit Tffd700${Te6edf3_phaseTffd700}Ta5d6ff Tffd700${Te6edf3_command_nameTffd700}Ta5d6ff"
Tff7b72fi

T8b949e# Stage and commit
Te6edf3_git_outTff7b72=Tff7b72$(git add . T79c0ff2>Tb4b4b4&T79c0ff1Tff7b72) Tff7b72|| Tff7b72{ Tffa657echo Ta5d6ff"Ta5d6ff[specify] Error: git add failed: Te6edf3$_git_outTa5d6ff" >Tb4b4b4&T79c0ff2Tb4b4b4; Tffa657exit T79c0ff1Tb4b4b4; Tff7b72}
Te6edf3_git_outTff7b72=Tff7b72$(git commit -q -m Ta5d6ff"Te6edf3$_commit_msgTa5d6ff" T79c0ff2>Tb4b4b4&T79c0ff1Tff7b72) Tff7b72|| Tff7b72{ Tffa657echo Ta5d6ff"Ta5d6ff[specify] Error: git commit failed: Te6edf3$_git_outTa5d6ff" >Tb4b4b4&T79c0ff2Tb4b4b4; Tffa657exit T79c0ff1Tb4b4b4; Tff7b72}

Tffa657echo Ta5d6ff"Ta5d6ff[OK] Changes committed Tffd700${Te6edf3_phaseTffd700}Ta5d6ff Tffd700${Te6edf3_command_nameTffd700}Ta5d6ff" >Tb4b4b4&T79c0ff2

Served by rngit 1.5.1 - Generated in 0.06s